/**
 * 直接加载：页面引入百度地图 API的脚本文件
 * 页面上添加一个 han-map-container元素，或者在已有元素上添加 han-map-container属性，作为地图容器的父元素.
 *
 * 异步加载：
 * 在地图容器的某个父元素上添加 han-map-loader属性，并将百度的图的 ak密钥设置为 an-map-loader的值。
 * 如需在页面加载时自动执行指定的地图方法，需要在 controller中关注 han.map.init。
 *
 * 屏蔽百度地图 LOGO及 LOGO后面文字的样式
 * div.anchorBL>a{display: none}
 * div.BMap_cpyCtrl.BMap_noprint.anchorBL{display: none}
 */
(function () {
	/* jshint unused: vars */
	/* globals BMap, angular  */
	"use strict";

	var app = angular.module('han.map', []);
	var defaultOptions = {
		center: '武汉',
		zoom: 12,
		dragging: true,
		scrollZoom: false,
		dbclickZoom: true,
		keyboard: false,
		inertialDragging: false,
		continuousZoom: false,
		pinchToZoom: true,
		autoResize: true,
		defaultCursor: null,
		draggingCursor: null,
		minZoom: null,
		maxZoom: null,
		control: [
			'NavigationControl',
			'ScaleControl',
			'MapTypeControl',
			'GeolocationControl'
        ]
	};

	function MapParams() {
		var params = { ak: '', v: '2.0' };
		return {
			setParams: function (p) {
				params = angular.extend(params, p);
			},
			$get: function () {
				return params;
			}
		};
	}

	/**
	 * 地图容器父元素
	 * attrs参数：
	 *    hanMapCache: 全局的地图缓存变量名，默认为 cachedMap
	 *    hanMapModal: scope中保存百度地图的BMap.Map对象的变量名，默认为 map
	 *    hanMapOptions: 地图初始化配置，覆盖默认的地图初始化配置，详见 defaultOptions
	 *    hanMapId: 地图容器元素的id，默认为 hanMap
	 *    hanMapWidth: 地图容器元素的宽度，默认 100%
	 *    hanMapHeight: 地图容器元素的宽度，默认 100%
	 */
	MapContainer.$inject = ['$parse', '$window', '$timeout', 'hanMapOptions'];
	function MapContainer($parse, $window, $timeout, hanMapOptions) {
		return {
			restrict: 'AE',
			link: function (scope, elem, attrs) {
				var mapCache = attrs.hanMapCache || 'cachedMap';
                var elemCache = mapCache + 'Elem';
				var map;
				var modal = attrs.hanMapModal || 'map';
				var options = attrs.hanMapOptions || '';
				var opts = angular.extend({}, hanMapOptions, scope[options]);
				var mapDiv = document.createElement('div');
				mapDiv.id = attrs.hanMapId || 'hanMap';
				mapDiv.style.width = attrs.hanMapWidth || '100%';
				mapDiv.style.height = attrs.hanMapHeight || '100%';

				if ($window.BMap && $window.BMap.Map) {
					/** 直接加载地图 */
					$timeout(function () {
						initMap();
					}, 200);
				} else {
					/** 异步加载地图 */
					scope.$on('han.map.load', function (event, param) {
						initMap();
					});
				}

				function initMap() {
                    if (mapCache !== "disable" && $window[mapCache] && $window[elemCache]) {
						elem[0].appendChild($window[elemCache]);
						map = $window[mapCache];
                    } else {
                        elem[0].appendChild(mapDiv);
                        map = new BMap.Map(mapDiv);

						if (opts.center && opts.zoom) map.centerAndZoom(opts.center, opts.zoom);
						else if (opts.center) map.setCenter(opts.center);
						else if (opts.zoom) map.setZoom(opts.zoom);
						if (opts.dragging) map.enableDragging(); else map.disableDragging();
						if (opts.scrollZoom) map.enableScrollWheelZoom(); else map.disableScrollWheelZoom();
						if (opts.dbclickZoom) map.enableDoubleClickZoom(); else map.disableDoubleClickZoom();
						if (opts.keyboard) map.enableKeyboard(); else map.disableKeyboard();
						if (opts.inertialDragging) map.enableInertialDragging(); else map.disableInertialDragging();
						if (opts.continuousZoom) map.enableContinuousZoom(); else map.disableContinuousZoom();
						if (opts.pinchToZoom) map.enablePinchToZoom(); else map.disablePinchToZoom();
						if (opts.autoResize) map.enableAutoResize(); else map.disableAutoResize();
						if (opts.defaultCursor) map.setDefaultCursor(opts.defaultCursor);
						if (opts.setDraggingCursor) map.setDraggingCursor(opts.DraggingCursor);
						if (opts.minZoom) map.setMinZoom(opts.minZoom);
						if (opts.maxZoom) map.setMaxZoom(opts.maxZoom);
						for (var idx in opts.control) {
							map.addControl(new BMap[opts.control[idx]]());
						}
					}

					scope.$on("$destroy", function () {
						if (!$window[mapCache] && mapCache !== "disable") $window[mapCache] = map;
						if (!$window[elemCache] && mapCache !== "disable") $window[elemCache] = mapDiv;
                    });

					modal = $parse(modal);
					modal.assign(scope, map);
					scope.$broadcast('han.map.init', true);
				}
			}
		};
	}

	/**
	 * 动态加载百度地图的js脚本
	 * attrs参数：
	 *    hanMapVersion: 百度地图API版本，默认2.0
	 *    hanMapLoader: 百度地图ak密钥，默认为空
	 */
	MapLoader.$inject = ['$window', 'hanMapParams'];
	function MapLoader($window, hanMapParams) {
		return {
            restrict: 'A',
			link: function (scope, elem, attrs) {
				$window.baiduLoadCallback = function () {
					scope.$broadcast('han.map.load', true);
				};
				var src = "https://api.map.baidu.com/api?callback=baiduLoadCallback";
				var v = "&v=" + (attrs.hanMapVersion || hanMapParams.v);
				var ak = "&ak=" + (attrs.hanMapLoader || hanMapParams.ak);
				var script = document.createElement("script");
				script.type = "text/javascript";
				script.src = src + v + ak;
                elem[0].appendChild(script);
                scope.$on("$destroy", function () {
                    elem.remove();
                });
			}
		};
	}

	app.value('hanMapOptions', defaultOptions);
	app.provider('hanMapParams', MapParams);
	app.directive('hanMapLoader', MapLoader);
    app.directive('hanMapContainer', MapContainer);
	app.factory('HanMapService',function(){
        return {
            boundary: function (map, area) {
                var pointArray = [];
                var bdary = new BMap.Boundary();
                bdary.get(area, function (rs) { // 获取行政区域
                    map.clearOverlays(); // 清除地图覆盖物
                    var count = rs.boundaries.length; // 行政区域的点有多少个
                    for (var i = 0; i < count; i++) {
                        var ply = new BMap.Polygon(rs.boundaries[i], {
                            strokeWeight: 2,
                            strokeColor: "#ff0000"
                        }); // 建立多边形覆盖物
                        map.addOverlay(ply); // 添加覆盖物
                        pointArray = pointArray.concat(ply.getPath());
                    }
                    map.setViewport(pointArray); // 调整视野
                });
                return pointArray;
            }
        };
	});

}).call(this);